<?php
// +-------------------------------------------------------------------------------
// | DingZone [ A Rapid Development Framework For Dingtalk ]
// +-------------------------------------------------------------------------------
// | 企业模块相关Controller v1.0
// |
// | Copyright (c) 2014-2018 http://www.heimalanshi.com All rights reserved.
// | Author : Jie
// | Date : 2018-08-09
// +-------------------------------------------------------------------------------

namespace app\core\controller\enterprise;

use app\core\model\EnterpriseModule;
use app\core\model\EnterpriseModuleApi;
use app\core\model\EnterpriseModuleAuthority;
use app\core\model\EnterpriseModuleConfig;
use app\core\model\SiteModule;
use app\core\model\SiteModuleWidget;
use ding\ApiHelper;
use app\core\controller\CoreBaseController;
use module\ModuleLoader;
use think\Cache;
use think\Loader;

/**
 * 企业模块管理
 *
 * @package app\core\controller\enterprise
 */
class ModuleController extends EnterpriseBaseController {
    protected $mid;
    protected $module;
    protected $enterpriseModule;

    /**
     * 构造函数
     * @throws \think\exception\DbException
     */
    public function __construct() {
        parent::__construct();

        $this->_initEnterpriseModule();
    }

    /**
     * 初始化当前模块信息
     *
     * @throws \think\exception\DbException
     */
    private function _initEnterpriseModule() {
        $this->mid = input("get.mid");
        $this->enterpriseModule = EnterpriseModule::getById($this->eid, $this->mid);
        if (empty($this->enterpriseModule)) {
            // 当前企业没有安装该模块
            $this->error("无权限访问该模块");
        }
        if ($this->enterpriseModule['status'] != EnterpriseModule::ENTERPRISE_MODULE_STATUS_NORMAL) {
            $this->error("该模块已过期或已停用");
        }

        // 判断模块本身的情况
        $this->module = SiteModule::getById($this->enterpriseModule['module_id']);
        if ($this->module['status'] != SiteModule::MODULE_STATUS_ACTIVE) {
            $this->error("该模块尚未激活");
        }
        $this->enterpriseModule['module'] = $this->module;

        $this->assign("enterpriseModule", $this->enterpriseModule);
        $this->assign("mid", $this->mid);
    }


    /**
     * 模块首页
     *
     * @return \think\response\View
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function home() {
        $widgetInfos = $this->_getWidgetInfos($this->module, "module");
        $this->assign("widgetInfos", $widgetInfos);
        return view();
    }

    /**
     * 获取挂件内容
     */
    public function widgetContent() {
        $name = input("post.name");
        $force = input("post.force");

        Loader::addNamespace("addons\\" . $this->module['name'] . "\\model",
            ROOT_PATH . "addons" . DS . $this->module['name'] . DS . "model");
        Loader::addNamespace("addons\\" . $this->module['name'] . "\\widget",
            ROOT_PATH . "addons" . DS . $this->module['name'] . DS . "widget");
        Loader::addNamespace("addons\\common\\widget",
            ROOT_PATH . "addons" . DS . "common" . DS . "widget");

        $packageName = "addons\\" . $this->module['name'] . "\\widget\\";
        $classFullName = $packageName . $name;
        Loader::import($classFullName, ROOT_PATH, EXT);
        $widgetClass = new $classFullName($this->enterprise, $this->module, $this->user);

        if ($force) {
            $widgetClass->clearCache();
        }
        $time = $widgetClass->getContentDataTime();
        $content = $widgetClass->getContent();
        if (!empty($time)) {
            $time = date('Y-m-d H:i:s', $time);
        }
        $this->success("数据获取成功", null, [
            'content' => $content,
            'time' => $time
        ]);
    }

    /**
     * 模块设置页面
     *
     * @return \think\response\View
     * @throws \think\exception\DbException
     */
    public function apiSetting() {
        $this->_checkEnterpriseModuleAdmin($this->mid);
        // 全部的api列表
        $apiHelper = new ApiHelper($this->enterprise, $this->enterpriseModule['module']);
        $allApis = $apiHelper->getApis();

        // 当前模块配置的api
        $enterpriseModuleApis = EnterpriseModuleApi::getAll($this->eid, $this->mid);
        $enterpriseModuleApis = remap($enterpriseModuleApis, 'api');

        foreach (ApiHelper::$apis as $name => $api) {
            if (isset($enterpriseModuleApis[$name])) {
                continue;
            }

            $enterpriseModuleApis[] = [
                'api' => $name,
                'status' => 'deny',
                'grant_fields' => ""
            ];
        }

        $apis = [];
        foreach ($enterpriseModuleApis as $enterpriseModuleApi) {
            $apiName = $enterpriseModuleApi['api'];
            $status = $enterpriseModuleApi['status'];
            $grantFields = $enterpriseModuleApi['grant_fields'];
            if (!isset($allApis[$apiName])) {
                continue;
            }

            $api = [];
            $api = array_merge($api, $allApis[$apiName]);
            $api['status'] = $status;
            $api['privacyFields'] = [];

            if (isset($allApis[$apiName]['privacySupportFields'])) {
                foreach ($allApis[$apiName]['privacySupportFields'] as $fieldName => $fieldDesc) {
                    // 字段默认不允许访问
                    $api['privacyFields'][$fieldName] = [
                        'desc' => $fieldDesc,
                        'status' => 'deny'
                    ];
                }
            }

            if (!empty($grantFields)) {
                // 授权访问的隐私字段设置成可以访问
                $grantFields = explode(',', $grantFields);
                foreach ($grantFields as $grantField) {
                    if (!isset($apis[$apiName]['privacyFields'][$grantField])) {
                        $apis[$apiName]['privacyFields'][$grantField] = [];
                    }
                    // 字段设置为可以访问
                    $api['privacyFields'][$grantField]['status'] = 'allow';
                }
            } else {
                //如果$grantFields为空，表示允许全部字段访问
                foreach ($api['privacyFields'] as &$privacyFields) {
                    $privacyFields['status'] = 'allow';
                }
            }

            if (empty($api['status'])) {
                $api['status'] = 'deny';
            }
            $api['api'] = $apiName;
            $apis[$apiName] = $api;
        }

        $sortedApis = [];
        foreach ($apis as $apiName => $api) {
            $sortedApis[$api['status'] . "_" . $apiName] = $api;
        }
        ksort($sortedApis);

        $this->assign("apis", $sortedApis);
        return view();
    }


    /**
     * 更改api状态
     *
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function updateApiStatus() {
        $this->_checkEnterpriseModuleAdmin($this->mid);
        $status = input("post.status");
        $apiName = input("post.apiName");
        if ($status != 'allow' && $status != 'deny') {
            $this->error("参数错误");
        }

        $ret = EnterpriseModuleApi::update($this->eid, $this->mid, $apiName, [
            'status' => $status
        ]);
        if ($ret) {
            $this->success("api状态设置成功");
        } else {
            $this->error("api状态设置失败");
        }
    }

    /**
     * 更新隐私字段
     *
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function updatePrivacyFields() {
        $this->_checkEnterpriseModuleAdmin($this->mid);
        $apiName = input("post.apiName");
        $fields = input("post.fields");

        $ret = EnterpriseModuleApi::update($this->eid, $this->mid, $apiName, [
            'grant_fields' => $fields
        ]);
        if ($ret) {
            $this->success("隐私字段设置成功");
        } else {
            $this->error("隐私字段设置失败");
        }
    }

    /**
     * 更新微应用设置
     *
     * @return \think\response\View
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     */
    public function agentSetting() {
        $this->_checkEnterpriseModuleAdmin($this->mid);
        if (is_submit()) {
            $agentId = input("post.agentId");
            EnterpriseModule::update(['agent_id' => $agentId], $this->mid, $this->eid);
            $this->success("更新成功");
        } else {
            return view();
        }
    }

    /**
     * 模块权限设置
     *
     * @return \think\response\View
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    public function authoritySetting() {
        $this->_checkEnterpriseModuleAdmin($this->mid);

        if (is_submit()) {
            // 模块管理员
            $adminers = input("post.adminers");
            EnterpriseModule::update([
                'adminers' => $adminers
            ], $this->mid, $this->eid);

            // 模块可见性
            $accessersType = input("post.accessers_type");
            $accessers = input("post.accessers");
            EnterpriseModule::update([
                'accessers' => json_encode([
                    'type' => $accessersType,
                    'list' => $accessers
                ])
            ], $this->mid, $this->eid);

            // 其他功能权限点
            $keys = input("post.key/a");
            if (!is_array($keys)) {
                $keys = [];
            }
            foreach ($keys as $idx => $key) {
                $entAdmin = input("post.entAdmin_" . ($idx + 1));
                $moduleAdmin = input("post.moduleAdmin_" . ($idx + 1));
                $other = input("post.other_" . ($idx + 1));
                $otherCdu = input("post.other_cdu_" . ($idx + 1));
                if ($other != 0 && $other != '0') {
                    $other = $otherCdu;
                }

                $value = [
                    'entAdmin' => $entAdmin,
                    'moduleAdmin' => $moduleAdmin,
                    'other' => $other
                ];

                EnterpriseModuleAuthority::upsert($this->eid, $this->mid, $key, $value);
            }

            $this->success("更新成功");
        } else {
            $authorities = EnterpriseModuleAuthority::getAll($this->eid, $this->mid);
            $groupAuthorities = EnterpriseModuleAuthority::groupAuthorities($authorities);

            $this->assign("groupAuthorities", $groupAuthorities);
            $this->assign("adminers", json_encode($this->enterpriseModule['adminers']));
            $this->assign("accessers", $this->enterpriseModule['accessers']);
            return view();
        }
    }

    /**
     * 模块相关配置
     *
     * @return \think\response\View
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function config() {
        $this->_checkEnterpriseModuleAdmin($this->mid);
        if (is_submit()) {
            $cfs = $this->request->post();
            unset($cfs['file']);
            foreach ($cfs as $key => $value) {
                EnterpriseModuleConfig::updateConfig($this->eid, $this->mid, $key, $value);
            }
            EnterpriseModuleConfig::clearCache($this->eid, $this->mid);
            $this->success("保存成功");
        } else {
            $enterpriseModuleConfigGroups = EnterpriseModuleConfig::getGroupConfigs($this->eid, $this->mid);
            $this->assign("configGroups", $enterpriseModuleConfigGroups);
            return view();
        }
    }
}